package analysis

import (
	"bytes"
	"encoding/binary"
	"io"
	"math"

	"gitee.com/yejia/radar/model"
)

// 解析二进制文件byte数组
func ParseBin(data []byte) (*model.RadarWrapper, error) {
	if len(data) == 0 {
		return nil, nil
	}
	// 创建一个 bytes.Reader 来读取数据
	reader := bytes.NewReader(data)
	return parseBin(reader)
}

// 解析二进制文件reader对象
func parseBin(reader io.Reader) (*model.RadarWrapper, error) {
	radarWrapper := model.RadarWrapper{}
	err := binary.Read(reader, binary.LittleEndian, &radarWrapper.GenericHeader) // 32
	if err != nil {
		return nil, err
	}
	err = binary.Read(reader, binary.LittleEndian, &radarWrapper.SiteConfiguration) // 128
	if err != nil {
		return nil, err
	}
	err = binary.Read(reader, binary.LittleEndian, &radarWrapper.TaskConfiguration) // 256
	if err != nil {
		return nil, err
	}
	if radarWrapper.TaskConfiguration.CutNumber > 0 {
		for i := 0; i < int(radarWrapper.TaskConfiguration.CutNumber); i++ {
			curConfiguration := make([]byte, 256)
			err = binary.Read(reader, binary.LittleEndian, &curConfiguration) // 256
			if err != nil {
				return nil, err
			}
		}
	}
	err = binary.Read(reader, binary.LittleEndian, &radarWrapper.ProductHeader) // 128
	if err != nil {
		return nil, err
	}
	err = binary.Read(reader, binary.LittleEndian, &radarWrapper.Params) // 64
	if err != nil {
		return nil, err
	}
	// 产品参数块
	err = binary.Read(reader, binary.LittleEndian, &radarWrapper.ProductRasterParams) // 64
	if err != nil {
		return nil, err
	}
	// PRODUCT DATA BLOCKS/产品数据块
	rsl := radarWrapper.ProductRasterParams.RowSideLength
	csl := radarWrapper.ProductRasterParams.ColumnSideLength
	binLength := radarWrapper.ProductRasterParams.BinLength

	offset := radarWrapper.ProductRasterParams.Offset
	scale := radarWrapper.ProductRasterParams.Scale
	dataResult := make([][]*float64, rsl)
	for i := range rsl {
		dataResult[i] = make([]*float64, csl)
		for j := range csl {
			if binLength == 1 {
				var v uint8
				err = binary.Read(reader, binary.LittleEndian, &v) // 64
				if err != nil {
					continue
				}
				if v < 5 {
					continue
				}
				s := math.Round(float64((int(v)-int(offset))*10/int(scale))) / 10
				dataResult[i][j] = &s
			}
		}
	}
	radarWrapper.Data = dataResult
	return &radarWrapper, nil
}
